package site.isscloud.project.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import site.isscloud.project.domain.PjAlarmEvent;
import site.isscloud.project.domain.PjLocation;
import site.isscloud.project.domain.PjLocationMarker;
import site.isscloud.project.dto.TemperatureTrendDTO;
import site.isscloud.project.mapper.PjLocationMapper;
import site.isscloud.project.mapper.PjLocationMarkerMapper;
import site.isscloud.project.mapper.PjStatsLocationTemperatureHourMapper;
import site.isscloud.project.mapper.PjStatsLocationTemperatureMinuteMapper;
import site.isscloud.project.service.BuildingService;
import site.isscloud.project.service.TemperatureTrendService;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.stream.Collectors;

@Service
public class BuildingServiceImpl implements BuildingService {

    private static final Logger logger = LoggerFactory.getLogger(BuildingServiceImpl.class);

    @Autowired
    private PjLocationMapper pjLocationMapper;

    @Autowired
    private PjLocationMarkerMapper pjLocationMarkerMapper;

    @Autowired
    private TemperatureTrendService temperatureTrendService;

    @Autowired
    private PjStatsLocationTemperatureMinuteMapper minuteMapper;

    @Autowired
    private PjStatsLocationTemperatureHourMapper hourMapper;

    @Override
    public Map<String, Object> getElevatorDetail(String lcIds) {
        Map<String, Object> result = new HashMap<>();

        // 获取电梯基本信息
        lcIds = lcIds.replace("\"", "");
        Long lcId = Long.parseLong(lcIds);
        PjLocation elevator = pjLocationMapper.selectPjLocationByLcId(lcId);
        if (elevator == null) {
            throw new RuntimeException("未找到对应的电梯信息");
        }

        // 生成实时图表数据
        Map<String, Object> realtimeChartData = generateRealtimeChartData(elevator);

        result.put("elevatorInfo", elevator);
        result.put("realtimeChartData", realtimeChartData);

        return result;
    }

    @Override
    public Map<String, Object> getTemperatureTrend(String lcIds, String timeType, Date startTime, Date endTime) {
        Map<String, Object> result = new HashMap<>();

        // 获取电梯基本信息
        lcIds = lcIds.replace("\"", "");
        Long lcId = Long.parseLong(lcIds);
        PjLocation elevator = pjLocationMapper.selectPjLocationByLcId(lcId);
        if (elevator == null) {
            throw new RuntimeException("未找到对应的电梯信息");
        }

        // 获取电梯的lc_code，用于匹配楼层
        String elevatorCode = elevator.getLcCode();
        if (elevatorCode == null || elevatorCode.isEmpty()) {
            throw new RuntimeException("电梯代码为空");
        }

        try {
            // 将 Date 转换为 LocalDateTime
            LocalDateTime startLocalDateTime = startTime.toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDateTime();
            LocalDateTime endLocalDateTime = endTime.toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDateTime();

            logger.info("查询温度趋势数据，电梯代码: {}, 时间类型: {}, 开始时间: {}, 结束时间: {}",
                    elevatorCode, timeType, startLocalDateTime, endLocalDateTime);

            // 获取该电梯下的所有楼层在时间范围内的趋势数据
            List<Map<String, Object>> floorTrendData;
            if ("hour".equals(timeType)) {
                floorTrendData = temperatureTrendService.getHourlyTrendByElevatorCode(elevatorCode, startLocalDateTime, endLocalDateTime);
            } else {
                floorTrendData = temperatureTrendService.getDailyTrendByElevatorCode(elevatorCode, startLocalDateTime, endLocalDateTime);
            }

            logger.info("获取到趋势数据条数: {}", floorTrendData.size());

            // 处理趋势数据格式
            Map<String, Object> trendChartData = processFloorTrendData(floorTrendData, timeType);
            result.put("trendChartData", trendChartData);

        } catch (Exception e) {
            logger.error("获取趋势数据失败，电梯ID: {}, 时间类型: {}, 错误信息: {}", lcId, timeType, e.getMessage(), e);
            throw new RuntimeException("获取趋势数据失败: " + e.getMessage(), e);
        }

        return result;
    }

    @Override
    public Map<String, Map<String, Object>> getLatestTemperatureStats() {
        try {
            // 使用现有的 minuteMapper 查询最新的温度统计数据
            List<Map<String, Object>> statsList = minuteMapper.selectLatestTemperatureStats();

            Map<String, Map<String, Object>> result = new HashMap<>();
            for (Map<String, Object> stat : statsList) {
                String lcCode = (String) stat.get("lc_code");
                if (lcCode != null) {
                    result.put(lcCode, stat);
                }
            }
            return result;
        } catch (Exception e) {
            logger.error("获取温度统计数据失败", e);
            return new HashMap<>();
        }
    }

    @Override
    public Map<String, Object> getTemperatureStatsByLocationCode(String lcCode) {
        try {
            // 查询指定位置的最新温度统计数据
            List<Map<String, Object>> statsList = minuteMapper.selectTemperatureStatsByLocationCode(lcCode);
            if (!statsList.isEmpty()) {
                return statsList.get(0);
            }
            return null;
        } catch (Exception e) {
            logger.error("根据位置编码获取温度统计数据失败: {}", lcCode, e);
            return null;
        }
    }

    @Override
    public List<String> getAbnormalFloors(PjLocation location, List<PjAlarmEvent> alarms) {
        List<String> abnormalFloors = new ArrayList<>();

        if (location.getLevel() != 5 || alarms.isEmpty()) {
            return abnormalFloors;
        }

        logger.info("开始计算异常楼层，电梯: {}, 告警数量: {}", location.getLcCode(), alarms.size());

        for (PjAlarmEvent alarm : alarms) {
            if (alarm.getMeterMark() != null) {
                logger.info("处理告警 - 米标: {}, 电梯范围: {}-{}",
                        alarm.getMeterMark(), location.getStartMeter(), location.getEndMeter());

                // 使用新的 calculateFloorFromMeter 方法，返回 String
                String floor = calculateFloorFromMeter(location, alarm.getMeterMark());
                if (floor != null) {
                    logger.info("计算楼层结果 - 米标: {} -> 楼层: {}", alarm.getMeterMark(), floor);
                    abnormalFloors.add(floor);
                } else {
                    logger.warn("未找到米标 {} 对应的楼层", alarm.getMeterMark());
                }
            }
        }

        logger.info("最终异常楼层: {}", abnormalFloors);
        // 去重
        return abnormalFloors.stream().distinct().collect(Collectors.toList());
    }


    @Override
    public List<String> getWarningFloors(PjLocation elevator) {
        List<String> warningFloors = new ArrayList<>();

        if (elevator == null || elevator.getLevel() != 5) {
            logger.warn("传入的位置不是电梯层级或为空");
            return warningFloors;
        }

        try {
            // 预警温度阈值（可根据实际需求调整）
            double warningTemperatureThreshold = 60.0;

            logger.info("开始获取预警楼层数据，电梯: {}", elevator.getLcCode());

            // 调用Mapper查询最新分钟级温度数据
            List<Map<String, Object>> recentTemperatureData =
                    minuteMapper.selectRecentTemperatureByElevator(elevator.getLcCode());

            logger.info("获取到最新温度数据条数: {}", recentTemperatureData.size());

            for (Map<String, Object> tempData : recentTemperatureData) {
                try {
                    Double temperature = convertToDouble(tempData.get("maxTemperature"));
                    String locationCode = (String) tempData.get("locationCode");

                    logger.debug("检查温度数据 - 位置: {}, 温度: {}, 阈值: {}",
                            locationCode, temperature, warningTemperatureThreshold);

                    if (temperature != null && temperature >= warningTemperatureThreshold && locationCode != null) {
                        // 从位置代码中提取楼层名称
                        String floorName = extractFloorNameFromLocationCode(elevator, locationCode);
                        if (floorName != null && !warningFloors.contains(floorName)) {
                            logger.info("发现预警楼层 - 楼层: {}, 温度: {}", floorName, temperature);
                            warningFloors.add(floorName);
                        }
                    }
                } catch (Exception e) {
                    logger.warn("处理单条温度数据时出错", e);
                    continue;
                }
            }

            logger.info("最终预警楼层列表: {}", warningFloors);
            return warningFloors;

        } catch (Exception e) {
            logger.error("获取预警楼层数据失败，电梯: {}", elevator.getLcCode(), e);
            return new ArrayList<>();
        }
    }

    /**
     * 从位置代码中提取楼层名称
     */
    private String extractFloorNameFromLocationCode(PjLocation elevator, String locationCode) {
        if (locationCode == null || elevator.getLcCode() == null) {
            return null;
        }

        try {
            // 电梯代码格式如: "SQ-A-1#-2U-1#"
            // 楼层位置代码格式如: "SQ-A-1#-2U-1#-B1L" 或 "SQ-A-1#-2U-1#-10L"
            String elevatorCode = elevator.getLcCode();

            if (locationCode.startsWith(elevatorCode)) {
                // 提取楼层部分
                String floorPart = locationCode.substring(elevatorCode.length());

                // 去掉开头的连接符（如果有）
                if (floorPart.startsWith("-")) {
                    floorPart = floorPart.substring(1);
                }

                // 如果楼层部分不为空，直接返回
                if (!floorPart.isEmpty()) {
                    logger.debug("提取楼层名称 - 位置代码: {} -> 楼层: {}", locationCode, floorPart);
                    return floorPart;
                }
            }

            // 备用方案：使用之前的方法提取楼层
            return extractFloorSuffix(locationCode);

        } catch (Exception e) {
            logger.warn("从位置代码提取楼层名称失败: {}", locationCode, e);
            return null;
        }
    }

    /**
     * 根据米标计算楼层 - 使用数据库标记数据
     */
    private String calculateFloorFromMeter(PjLocation elevator, Integer meterMark) {
        if (elevator.getStartMeter() == null || elevator.getEndMeter() == null || meterMark == null) {
            logger.warn("参数为空，无法计算楼层");
            return null;
        }

        logger.info("计算楼层 - 电梯: {}, 米标: {}, 范围: {}-{}",
                elevator.getLcCode(), meterMark, elevator.getStartMeter(), elevator.getEndMeter());

        try {
            // 方法1：直接根据米标范围查询对应的楼层标记
            PjLocationMarker marker = pjLocationMarkerMapper.selectMarkerByMeterRange(elevator.getLcCode(), meterMark);
            if (marker != null) {
                String floor = extractFloorNumberFromLcCode(marker.getLcCode());
                if (floor != null) {
                    logger.info("通过标记找到楼层 - 标记: {} -> 楼层: {}", marker.getLcCode(), floor);
                    return floor;
                }
            }

            // 方法2：如果直接查询没找到，获取所有子级标记再查找
            List<PjLocationMarker> markers = pjLocationMarkerMapper.selectChildMarkersByParentCode(elevator.getLcCode());
            logger.info("获取到子级标记数量: {}", markers != null ? markers.size() : 0);

            if (markers != null && !markers.isEmpty()) {
                for (PjLocationMarker childMarker : markers) {
                    if (childMarker.getMarkerStart() != null && childMarker.getMarkerEnd() != null) {
                        logger.info("检查标记 - {}: {}-{}", childMarker.getLcCode(), childMarker.getMarkerStart(), childMarker.getMarkerEnd());
                        if (meterMark >= childMarker.getMarkerStart() && meterMark <= childMarker.getMarkerEnd()) {
                            String floor = extractFloorNumberFromLcCode(childMarker.getLcCode());
                            if (floor != null) {
                                logger.info("找到匹配标记 - 楼层: {}", floor);
                                return floor;
                            }
                        }
                    }
                }
            }

            logger.warn("未找到电梯 {} 米标 {} 对应的楼层标记", elevator.getLcCode(), meterMark);
            return null;

        } catch (Exception e) {
            logger.error("计算楼层失败，电梯: {}, 米标: {}", elevator.getLcCode(), meterMark, e);
            return null;
        }
    }

    /**
     * 从lc_code中提取楼层号 - 直接返回楼层标识
     */
    private String extractFloorNumberFromLcCode(String lcCode) {
        if (lcCode == null) {
            return null;
        }

        try {
            // 提取最后一个 "-" 后面的部分，如 "1L", "B1", "10L", "B1L" 等
            int lastDashIndex = lcCode.lastIndexOf("-");
            if (lastDashIndex != -1 && lastDashIndex < lcCode.length() - 1) {
                String floorPart = lcCode.substring(lastDashIndex + 1);
                logger.info("解析楼层标识: {}", floorPart);

                // 直接返回楼层标识，不做任何转换
                return floorPart;
            }
        } catch (Exception e) {
            logger.warn("无法从lc_code解析楼层号: {}", lcCode);
        }

        return null;
    }

    /**
     * 默认楼层计算（备用方案）
     */
    private int calculateFloorByDefault(PjLocation elevator, Integer meterMark) {
        // 保持原有的计算逻辑作为备用
        int totalMeters = elevator.getEndMeter() - elevator.getStartMeter();
        int relativeMeter = meterMark - elevator.getStartMeter();
        int metersPerFloor = 3;
        int floor = (relativeMeter / metersPerFloor) + 1;
        return Math.max(1, floor);
    }

    /**
     * 处理楼层趋势数据格式
     */
    private Map<String, Object> processFloorTrendData(List<Map<String, Object>> floorTrendData, String timeType) {
        Map<String, Object> result = new HashMap<>();

        if (floorTrendData == null || floorTrendData.isEmpty()) {
            result.put("timeLabels", new ArrayList<>());
            result.put("meterData", new ArrayList<>());
            return result;
        }

        // 按时间分组，生成时间标签
        Set<String> timeSet = new TreeSet<>();
        Map<String, List<Map<String, Object>>> dataByMeter = new HashMap<>();

        SimpleDateFormat sdf;
        if ("hour".equals(timeType)) {
            sdf = new SimpleDateFormat("MM-dd HH:mm");
        } else {
            // 按天显示时，可以按小时或保持原始时间粒度
            sdf = new SimpleDateFormat("MM-dd HH:00"); // 或者 "MM-dd" 如果您确实需要按天聚合
        }

        // 组织数据：按楼层分组，并收集所有时间点
        for (Map<String, Object> data : floorTrendData) {
            if (data == null) {
                continue;
            }

            try {
                // 处理 statTime 字段
                Object statTimeObj = data.get("statTime");
                if (statTimeObj == null) {
                    logger.warn("statTime 为 null，跳过该数据");
                    continue;
                }

                Date statTime = convertToDate(statTimeObj);
                if (statTime == null) {
                    logger.warn("无法转换 statTime: {}", statTimeObj);
                    continue;
                }

                String timeLabel = sdf.format(statTime);
                timeSet.add(timeLabel);

                // 获取楼层标识
                String lcCode = (String) data.get("lcCode");
                if (lcCode == null) {
                    lcCode = (String) data.get("locationCode"); // 尝试其他可能的字段名
                }

                String meterMark = extractFloorSuffix(lcCode);
                if (meterMark == null) {
                    meterMark = "unknown"; // 防止空指针
                }

                if (!dataByMeter.containsKey(meterMark)) {
                    dataByMeter.put(meterMark, new ArrayList<>());
                }
                dataByMeter.get(meterMark).add(data);
            } catch (Exception e) {
                logger.warn("处理趋势数据时出错，跳过该条数据: {}", e.getMessage());
                continue;
            }
        }

        List<String> timeLabels = new ArrayList<>(timeSet);

        // 为每个楼层生成温度数据数组
        List<Map<String, Object>> meterDataList = new ArrayList<>();

        for (Map.Entry<String, List<Map<String, Object>>> entry : dataByMeter.entrySet()) {
            String meterMark = entry.getKey();
            List<Map<String, Object>> meterData = entry.getValue();

            if (meterData == null || meterData.isEmpty()) {
                continue;
            }

            try {
                // 按时间排序
                meterData.sort((a, b) -> {
                    try {
                        Object timeAObj = a.get("statTime");
                        Object timeBObj = b.get("statTime");
                        LocalDateTime timeA = convertToLocalDateTime(timeAObj);
                        LocalDateTime timeB = convertToLocalDateTime(timeBObj);
                        return timeA.compareTo(timeB);
                    } catch (Exception e) {
                        logger.warn("时间排序失败: {}", e.getMessage());
                        return 0;
                    }
                });

                // 生成该楼层的温度数据数组 - 取最大值
                List<Double> temperatureValues = new ArrayList<>();
                for (String timeLabel : timeLabels) {
                    Double temperature = findMaxTemperatureForTime(meterData, timeLabel, sdf);
                    temperatureValues.add(temperature != null ? temperature : 0.0);
                }

                Map<String, Object> meterDataMap = new HashMap<>();
                meterDataMap.put("meterMark", meterMark);
                meterDataMap.put("temperatureValues", temperatureValues);
                meterDataList.add(meterDataMap);
            } catch (Exception e) {
                logger.warn("处理楼层 {} 数据时出错: {}", meterMark, e.getMessage());
                continue;
            }
        }

        result.put("timeLabels", timeLabels);
        result.put("meterData", meterDataList);

        logger.debug("处理完成趋势数据: {} 个时间点, {} 个楼层", timeLabels.size(), meterDataList.size());
        return result;
    }

    /**
     * 将对象转换为 Date
     */
    private Date convertToDate(Object timeObj) {
        if (timeObj == null) {
            return null;
        }

        try {
            if (timeObj instanceof LocalDateTime) {
                return Date.from(((LocalDateTime) timeObj).atZone(ZoneId.systemDefault()).toInstant());
            } else if (timeObj instanceof java.util.Date) {
                return (java.util.Date) timeObj;
            } else if (timeObj instanceof java.sql.Date) {
                // 处理 java.sql.Date
                java.sql.Date sqlDate = (java.sql.Date) timeObj;
                return new java.util.Date(sqlDate.getTime());
            } else if (timeObj instanceof java.sql.Timestamp) {
                // 处理 java.sql.Timestamp
                java.sql.Timestamp timestamp = (java.sql.Timestamp) timeObj;
                return new java.util.Date(timestamp.getTime());
            } else if (timeObj instanceof String) {
                // 尝试解析字符串格式的时间
                try {
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    return dateFormat.parse((String) timeObj);
                } catch (Exception e) {
                    logger.warn("无法解析时间字符串: {}", timeObj);
                    return null;
                }
            }
        } catch (Exception e) {
            logger.warn("转换时间对象失败: {}, 类型: {}", timeObj, timeObj.getClass().getName(), e);
        }

        return null;
    }

    /**
     * 将对象转换为 LocalDateTime
     */
    private LocalDateTime convertToLocalDateTime(Object timeObj) {
        if (timeObj == null) {
            return LocalDateTime.now();
        }

        try {
            if (timeObj instanceof LocalDateTime) {
                return (LocalDateTime) timeObj;
            } else if (timeObj instanceof java.util.Date) {
                return ((java.util.Date) timeObj).toInstant()
                        .atZone(ZoneId.systemDefault())
                        .toLocalDateTime();
            } else if (timeObj instanceof java.sql.Date) {
                // 处理 java.sql.Date 类型
                java.sql.Date sqlDate = (java.sql.Date) timeObj;
                return sqlDate.toLocalDate().atStartOfDay();
            } else if (timeObj instanceof java.sql.Timestamp) {
                // 处理 java.sql.Timestamp 类型
                java.sql.Timestamp timestamp = (java.sql.Timestamp) timeObj;
                return timestamp.toLocalDateTime();
            } else if (timeObj instanceof String) {
                // 尝试解析字符串格式的时间
                try {
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    Date date = dateFormat.parse((String) timeObj);
                    return date.toInstant()
                            .atZone(ZoneId.systemDefault())
                            .toLocalDateTime();
                } catch (Exception e) {
                    logger.warn("无法解析时间字符串: {}", timeObj);
                    return LocalDateTime.now();
                }
            }
        } catch (Exception e) {
            logger.warn("转换 LocalDateTime 失败: {}, 类型: {}", timeObj, timeObj.getClass().getName(), e);
        }

        return LocalDateTime.now();
    }

    /**
     * 查找指定时间的最大温度数据
     */
    private Double findMaxTemperatureForTime(List<Map<String, Object>> meterData, String timeLabel, SimpleDateFormat sdf) {
        if (meterData == null || meterData.isEmpty()) {
            return null;
        }

        for (Map<String, Object> data : meterData) {
            if (data == null) {
                continue;
            }

            try {
                Object statTimeObj = data.get("statTime");
                Date statTime = convertToDate(statTimeObj);
                if (statTime == null) {
                    continue;
                }

                String dataTimeLabel = sdf.format(statTime);
                if (timeLabel.equals(dataTimeLabel)) {
                    // 优先取 maxTemperature，如果没有则取 avgTemperature
                    Object tempObj = data.get("maxTemperature");
                    if (tempObj == null) {
                        tempObj = data.get("avgTemperature");
                    }

                    return convertToDouble(tempObj);
                }
            } catch (Exception e) {
                logger.warn("查找温度数据时出错: {}", e.getMessage());
                continue;
            }
        }
        return null;
    }

    /**
     * 从lcCode中提取楼层标识
     */
    private String extractFloorSuffix(String lcCode) {
        if (lcCode == null) {
            return "unknown";
        }

        try {
            // 假设电梯代码格式为 "SQ-A-1#-2U-1#-B1L"，楼层标识在最后一个"-"之后
            int lastDashIndex = lcCode.lastIndexOf("-");
            if (lastDashIndex != -1 && lastDashIndex < lcCode.length() - 1) {
                String suffix = lcCode.substring(lastDashIndex + 1);
                // 去掉开头的"-"（如果有）
                if (suffix.startsWith("-")) {
                    suffix = suffix.substring(1);
                }
                return suffix;
            }
            return lcCode;
        } catch (Exception e) {
            logger.warn("提取楼层后缀失败: {}", lcCode, e);
            return lcCode;
        }
    }

    /**
     * 数值类型转换工具方法
     */
    private Double convertToDouble(Object value) {
        if (value == null) {
            return null;
        }

        try {
            if (value instanceof BigDecimal) {
                return ((BigDecimal) value).doubleValue();
            } else if (value instanceof Double) {
                return (Double) value;
            } else if (value instanceof Float) {
                return ((Float) value).doubleValue();
            } else if (value instanceof Integer) {
                return ((Integer) value).doubleValue();
            } else if (value instanceof Long) {
                return ((Long) value).doubleValue();
            } else if (value instanceof String) {
                try {
                    return Double.parseDouble((String) value);
                } catch (NumberFormatException e) {
                    logger.warn("无法解析数字字符串: {}", value);
                    return null;
                }
            }
        } catch (Exception e) {
            logger.warn("转换数值失败: {}, 类型: {}", value, value.getClass().getName(), e);
        }

        return null;
    }


    /**
     * 查找指定时间的温度数据
     */
    private Double findTemperatureForTime(List<Map<String, Object>> meterData, String timeLabel, SimpleDateFormat sdf) {
        for (Map<String, Object> data : meterData) {
            Object statTimeObj = data.get("statTime");
            Date statTime;
            try {
                if (statTimeObj instanceof LocalDateTime) {
                    statTime = Date.from(((LocalDateTime) statTimeObj).atZone(ZoneId.systemDefault()).toInstant());
                } else if (statTimeObj instanceof java.util.Date) {
                    statTime = (java.util.Date) statTimeObj;
                } else if (statTimeObj instanceof java.sql.Date) {
                    // 处理 java.sql.Date
                    java.sql.Date sqlDate = (java.sql.Date) statTimeObj;
                    statTime = new java.util.Date(sqlDate.getTime());
                } else if (statTimeObj instanceof java.sql.Timestamp) {
                    // 处理 java.sql.Timestamp
                    java.sql.Timestamp timestamp = (java.sql.Timestamp) statTimeObj;
                    statTime = new java.util.Date(timestamp.getTime());
                } else {
                    continue;
                }

                String dataTimeLabel = sdf.format(statTime);
                if (timeLabel.equals(dataTimeLabel)) {
                    Object tempObj = data.get("avgTemperature");
                    if (tempObj instanceof BigDecimal) {
                        return ((BigDecimal) tempObj).doubleValue();
                    } else if (tempObj instanceof Double) {
                        return (Double) tempObj;
                    } else if (tempObj instanceof Float) {
                        return ((Float) tempObj).doubleValue();
                    } else if (tempObj instanceof Integer) {
                        return ((Integer) tempObj).doubleValue();
                    }
                }
            } catch (Exception e) {
                logger.warn("处理温度数据时出错", e);
                continue;
            }
        }
        return null;
    }

    // 其他方法保持不变（generateRealtimeChartData, generateTrendChartData, processTrendData, getLatestTemperatureByLcId, calculateMeterFromFloor 等）
    // 这些方法不需要修改，因为它们不涉及时间类型的转换问题

    @Override
    public Map<String, Object> generateRealtimeChartData(PjLocation elevator) {
        // 原有实现保持不变
        Map<String, Object> chartData = new HashMap<>();

        // 获取电梯的实际米标范围
        Integer startMeter = elevator.getStartMeter();
        Integer endMeter = elevator.getEndMeter();

        if (startMeter == null || endMeter == null || startMeter >= endMeter) {
            chartData.put("seriesData", new ArrayList<>());
            chartData.put("startMeter", 0);
            chartData.put("endMeter", 0);
            return chartData;
        }

        List<Map<String, Object>> seriesData = new ArrayList<>();

        // 从数据库获取最新的实时温度数据
        List<Map<String, Object>> temperatureData = getLatestTemperatureByLcId(elevator.getLcId().toString());

        if (temperatureData.isEmpty()) {
            // 如果没有实时数据，使用模拟数据
            Random random = new Random();
            for (int meter = startMeter; meter <= endMeter; meter++) {
                double temperature = 25 + random.nextDouble() * 40; // 25-65度
                addTemperaturePoint(seriesData, meter, temperature);
            }
        } else {
            // 使用实际数据 - 包含完整信息
            for (Map<String, Object> tempData : temperatureData) {
                Integer meter = (Integer) tempData.get("meter");
                Double minTemperature = convertToDouble(tempData.get("minTemperature"));
                Double maxTemperature = convertToDouble(tempData.get("maxTemperature"));
                Double avgTemperature = convertToDouble(tempData.get("avgTemperature"));

                if (meter != null && minTemperature != null && maxTemperature != null) {
                    // 创建包含完整信息的数据点
                    Map<String, Object> point = new HashMap<>();

                    // 基础信息
                    point.put("meter", meter);
                    point.put("minTemperature", minTemperature);
                    point.put("maxTemperature", maxTemperature);
                    point.put("avgTemperature", avgTemperature != null ? avgTemperature : (minTemperature + maxTemperature) / 2);

                    // 完整设备信息
                    point.put("lcCode", tempData.get("lcCode"));
                    point.put("deviceNo", tempData.get("deviceNo"));
                    point.put("channelNo", tempData.get("channelNo"));
                    point.put("statTime", tempData.get("statTime"));
                    point.put("markerCount", tempData.get("markerCount"));
                    point.put("sampleCount", tempData.get("sampleCount"));
                    point.put("floorName", tempData.get("floorName"));

                    // 根据最高温度设置颜色
                    if (maxTemperature > 60) {
                        point.put("color", "#f5222d"); // 红色-危险
                    } else if (maxTemperature > 50) {
                        point.put("color", "#faad14"); // 黄色-预警
                    } else {
                        point.put("color", "#1890ff"); // 蓝色-正常
                    }

                    seriesData.add(point);
                }
            }

            // 如果没有完整数据但有平均温度，使用旧格式（兼容性）
            if (seriesData.isEmpty()) {
                for (Map<String, Object> tempData : temperatureData) {
                    Integer meter = (Integer) tempData.get("meter");
                    Double temperature = convertToDouble(tempData.get("avgTemperature"));
                    if (meter != null && temperature != null) {
                        addTemperaturePoint(seriesData, meter, temperature);
                    }
                }
            }
        }

        chartData.put("seriesData", seriesData);
        chartData.put("startMeter", startMeter);
        chartData.put("endMeter", endMeter);

        return chartData;
    }

    /**
     * 添加温度数据点（兼容旧格式）
     */
    private void addTemperaturePoint(List<Map<String, Object>> seriesData, int meter, double temperature) {
        Map<String, Object> point = new HashMap<>();
        point.put("meter", meter);
        point.put("temperature", Math.round(temperature * 10) / 10.0);

        // 根据温度设置颜色
        if (temperature > 60) {
            point.put("color", "#f5222d"); // 红色-危险
        } else if (temperature > 50) {
            point.put("color", "#faad14"); // 黄色-预警
        } else {
            point.put("color", "#1890ff"); // 蓝色-正常
        }

        seriesData.add(point);
    }



    @Override
    public Map<String, Object> generateTrendChartData(PjLocation elevator, String timeType) {
        Map<String, Object> chartData = new HashMap<>();

        // 计算精确的时间范围
        Calendar calendar = Calendar.getInstance();
        Date endTime = calendar.getTime();
        Date startTime;

        if ("hour".equals(timeType)) {
            // 按小时：获取最近24小时数据
            calendar.add(Calendar.HOUR_OF_DAY, -24);
            startTime = calendar.getTime();

            // 转换为 LocalDateTime
            LocalDateTime startLocalDateTime = startTime.toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDateTime();
            LocalDateTime endLocalDateTime = endTime.toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDateTime();

            List<TemperatureTrendDTO> trendData = temperatureTrendService.getHourlyTrendByLcId(
                    elevator.getLcId().toString(), startLocalDateTime, endLocalDateTime);

            chartData = processTrendData(trendData, timeType);

        } else if ("day".equals(timeType)) {
            // 按天：获取精确的24小时数据，而不是简单的7天前
            calendar.add(Calendar.DAY_OF_MONTH, -1); // 精确的24小时前
            startTime = calendar.getTime();

            // 转换为 LocalDateTime
            LocalDateTime startLocalDateTime = startTime.toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDateTime();
            LocalDateTime endLocalDateTime = endTime.toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDateTime();

            // 使用从小时表获取天趋势数据的方法
            List<Map<String, Object>> trendData = temperatureTrendService.getDailyTrendByElevatorCodeFromHourTable(
                    elevator.getLcCode(), startLocalDateTime, endLocalDateTime);

            chartData = processFloorTrendData(trendData, timeType);
        }

        return chartData;
    }


    /**
     * 处理趋势数据格式
     */
    private Map<String, Object> processTrendData(List<TemperatureTrendDTO> trendData, String timeType) {
        Map<String, Object> result = new HashMap<>();

        if (trendData.isEmpty()) {
            result.put("timeLabels", new ArrayList<>());
            result.put("temperatureData", new ArrayList<>());
            return result;
        }

        // 生成时间标签
        List<String> timeLabels = new ArrayList<>();
        List<Double> temperatureData = new ArrayList<>();

        SimpleDateFormat sdf;
        if ("hour".equals(timeType)) {
            sdf = new SimpleDateFormat("HH:mm");
        } else {
            sdf = new SimpleDateFormat("MM-dd");
        }

        for (TemperatureTrendDTO data : trendData) {
            // 处理 LocalDateTime 类型的时间 - 修复这里
            Object timeObj = data.getTime();
            if (timeObj instanceof LocalDateTime) {
                Date date = Date.from(((LocalDateTime) timeObj).atZone(ZoneId.systemDefault()).toInstant());
                timeLabels.add(sdf.format(date));
            } else if (timeObj instanceof Date) {
                timeLabels.add(sdf.format((Date) timeObj));
            } else {
                // 其他类型，使用当前时间
                timeLabels.add(sdf.format(new Date()));
            }
            temperatureData.add(data.getTemperature().doubleValue());
        }

        result.put("timeLabels", timeLabels);
        result.put("temperatureData", temperatureData);

        return result;
    }

    /**
     * 获取电梯各楼层最新温度数据
     */
    public List<Map<String, Object>> getLatestTemperatureByLcId(String lcIds) {
        List<Map<String, Object>> result = new ArrayList<>();

        lcIds = lcIds.replace("\"", "");
        Long lcId = Long.parseLong(lcIds);

        // 获取电梯信息
        PjLocation elevator = pjLocationMapper.selectPjLocationByLcId(lcId);
        if (elevator == null) {
            return result;
        }

        // 获取电梯的lc_code，用于匹配楼层
        String elevatorCode = elevator.getLcCode();
        if (elevatorCode == null || elevatorCode.isEmpty()) {
            return result;
        }

        // 通过电梯lc_code获取对应楼层的最新温度数据
        List<Map<String, Object>> floorTemperatureData = minuteMapper.selectLatestFloorTemperatureByElevatorCode(elevatorCode);

        // 处理实际的楼层温度数据
        for (Map<String, Object> floorData : floorTemperatureData) {
            Map<String, Object> tempPoint = new HashMap<>();
            // 完整信息
            tempPoint.put("lcCode", floorData.get("locationCode"));
            tempPoint.put("deviceNo", floorData.get("deviceNo"));
            tempPoint.put("channelNo", floorData.get("channelNo"));
            tempPoint.put("statTime", floorData.get("recordTime"));
            tempPoint.put("maxTemperature", floorData.get("maxTemperature"));
            tempPoint.put("minTemperature", floorData.get("minTemperature"));
            tempPoint.put("avgTemperature", floorData.get("avgTemperature"));
            tempPoint.put("markerCount", floorData.get("markerCount"));
            tempPoint.put("sampleCount", floorData.get("sampleCount"));

            // 从locationCode中提取楼层信息和米标
            String locationCode = (String) floorData.get("locationCode");
            if (locationCode != null && locationCode.startsWith(elevatorCode)) {
                // 提取楼层标识，如 "-10L" -> "10L"
                String floorSuffix = locationCode.substring(elevatorCode.length());

                // 处理楼层名称：去掉开头的 "-"
                String floorName = floorSuffix;
                if (floorName.startsWith("-")) {
                    floorName = floorName.substring(1); // 去掉开头的 "-"
                }
                tempPoint.put("floorName", floorName);

                // 根据楼层标识计算米标
                Integer meter = calculateMeterFromFloor(floorName, elevator.getStartMeter(), elevator.getEndMeter());
                tempPoint.put("meter", meter);
            }

            // 根据最高温度设置颜色
            Double maxTemp = convertToDouble(floorData.get("maxTemperature"));
            if (maxTemp != null) {
                if (maxTemp > 60) {
                    tempPoint.put("color", "#f5222d");
                } else if (maxTemp > 50) {
                    tempPoint.put("color", "#faad14");
                } else {
                    tempPoint.put("color", "#1890ff");
                }
            } else {
                tempPoint.put("color", "#1890ff");
            }

            result.add(tempPoint);
        }

        return result;
    }

    /**
     * 根据楼层标识计算米标
     */
    private Integer calculateMeterFromFloor(String floorName, Integer startMeter, Integer endMeter) {
        if (floorName == null || floorName.isEmpty()) {
            return 0;
        }

        try {
            // 解析楼层号，如 "10L" -> 10, "B1" -> -1
            String floorNumStr = floorName.replaceAll("[^\\d-]", "");
            if (!floorNumStr.isEmpty()) {
                int floorNum = Integer.parseInt(floorNumStr);

                // 简单的米标计算：假设每层3米
                int meter = floorNum * 3;

                // 确保米标在合理范围内
                if (startMeter != null && endMeter != null) {
                    return Math.max(startMeter, Math.min(endMeter, meter));
                }

                return meter;
            }
        } catch (NumberFormatException e) {
            // 解析失败，返回默认值
        }

        return 0;
    }
}